home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / cp2dekit / samples / xmpplay.cpp < prev   
C/C++ Source or Header  |  1996-12-29  |  13KB  |  546 lines

  1. //***************************************************************************
  2. //
  3. // this file is (c) '94-'96 Niklas Beisert
  4. //
  5. // this file is part of the cubic player development kit.
  6. // you may only use/modify/spread this file under the terms stated
  7. // in the cubic player development kit accompanying documentation.
  8. //
  9. //***************************************************************************
  10.  
  11.  
  12. // interface example
  13.  
  14. #include <time.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <conio.h>
  18. #include "pfilesel.h"
  19. #include "mcp.h"
  20. #include "psetting.h"
  21. #include "binfile.h"
  22. #include "dpmi.h"
  23. #include "poutput.h"
  24. #include "err.h"
  25. #include "plinkman.h"
  26. #include "deviwave.h"
  27. #include "cpiface.h"
  28. #include "xmplay.h"
  29. #include "gmdinst.h"
  30.  
  31.  
  32. extern int plLoopMods;
  33.  
  34. static xmodule mod;
  35.  
  36. void mcpDrawGStrings(short (*)[132]);
  37. void mcpNormalize();
  38. int mcpSetProcessKey(unsigned short);
  39.  
  40. static instrument *insts;
  41. static sample *samps;
  42.  
  43. static int xmpProcessKey(unsigned short key)
  44. {
  45.   if (mcpSetProcessKey(key))
  46.     return 1;
  47.   if (mcpProcessKey)
  48.   {
  49.     int ret=mcpProcessKey(key);
  50.     if (ret==2)
  51.       cpiResetScreen();
  52.     if (ret)
  53.      return 1;
  54.   }
  55.   int pat,row,p;
  56.   switch (key)
  57.   {
  58.   case 'p': case 'P': case 0x10:
  59.     mcpSet(-1, mcpMasterPause, plPause^=1);
  60.     plChanChanged=1;
  61.     break;
  62.   case 0x7700: //ctrl-home
  63.     gmdInstClear();
  64.  
  65.     xmpSetPos(0, 0);
  66.     break;
  67.   case 0x7300: //ctrl-left
  68.     p=xmpGetPos();
  69.     pat=p>>8;
  70.     xmpSetPos(pat-1, 0);
  71.     break;
  72.   case 0x7400: //ctrl-right
  73.     p=xmpGetPos();
  74.     pat=p>>8;
  75.     xmpSetPos(pat+1, 0);
  76.     break;
  77.   case 0x8D00: // ctrl-up
  78.     p=xmpGetPos();
  79.     pat=p>>8;
  80.     row=p&0xFF;
  81.     xmpSetPos(pat, row-8);
  82.     break;
  83.   case 0x9100: //ctrl-down
  84.     p=xmpGetPos();
  85.     pat=p>>8;
  86.     row=p&0xFF;
  87.     xmpSetPos(pat, row+8);
  88.     break;
  89.   }
  90.   return 1;
  91. }
  92.  
  93. static int xmpLooped()
  94. {
  95.   return !plLoopMods&&xmpLoop();
  96. }
  97.  
  98. static void xmpIdle()
  99. {
  100.   xmpSetLoop(plLoopMods);
  101.   if (mcpIdle)
  102.     mcpIdle();
  103. }
  104.  
  105. static void xmpDrawGStrings(short (*buf)[132])
  106. {
  107.   writestring(buf[0], 0, 0, "", 132);
  108.   writestring(buf[1], 0, 0, "", 132);
  109.   writestring(buf[2], 0, 0, "", 132);
  110.   mcpDrawGStrings(buf);
  111.   writenum(buf[2], 2, 0x07, xmpGetPos(), 16, 4, 0);
  112.   writenum(buf[2], 8, 0x07, mcpGet(-1, mcpGTimer), 16, 8, 0);
  113. }
  114.  
  115. static void xmpCloseFile()
  116. {
  117.   xmpStopModule();
  118.   xmpFreeModule(mod);
  119. }
  120.  
  121. //**********************************************************************
  122.  
  123. static void xmpMarkInsSamp(char *ins, char *smp)
  124. {
  125.   int i;
  126.   for (i=0; i<plNLChan; i++)
  127.   {
  128.     if (!xmpChanActive(i))
  129.       continue;
  130.     int in=xmpGetChanIns(i);
  131.     int sm=xmpGetChanSamp(i);
  132.     ins[in-1]=((plSelCh==i)||(ins[in-1]==3))?3:2;
  133.     smp[sm]=((plSelCh==i)||(smp[sm]==3))?3:2;
  134.   }
  135. }
  136.  
  137. //**********************************************************************
  138.  
  139. static int patwidth;
  140. static int patheight;
  141. static int patfirst;
  142.  
  143. static void xmpDrawPattern(int sel)
  144. {
  145.   unsigned short xmpos=xmpGetPos();
  146.   int ord=xmpos>>8;
  147.   int pat=mod.orders[ord];
  148.   int row=xmpos&0xFF;
  149.   int ch=plSelCh;
  150.   int row0=row-patheight/3;
  151.   int patlen=mod.patlens[pat];
  152.   int i;
  153.   for (i=0; i<patheight; i++)
  154.   {
  155.     int r=row0+i;
  156.     short buf[132];
  157.     writestring(buf, 0, 0, "", patwidth);
  158.     if ((r>=0)&&(r<patlen))
  159.     {
  160.       unsigned char *fx=mod.patterns[pat][mod.nchan*r+ch];
  161.       writestring(buf, 0, 0x08, "·· ··  ··  ·· ··", 16);
  162.       if (fx[0])
  163.         writenum(buf, 0, 0x07, fx[0], 16, 2, 0);
  164.       if (fx[1])
  165.         writenum(buf, 3, 0x07, fx[1], 16, 2, 0);
  166.       if (fx[2])
  167.         writenum(buf, 7, 0x07, fx[2], 16, 2, 0);
  168.       if (fx[3]||fx[4])
  169.       {
  170.         writenum(buf, 11, 0x07, fx[3], 16, 2, 0);
  171.         writenum(buf, 14, 0x07, fx[4], 16, 2, 0);
  172.       }
  173.     }
  174.     int j;
  175.     if (r==row)
  176.       for (j=0; j<patwidth; j++)
  177.         buf[j]|=0x8800;
  178.     displaystrattr(patfirst+i, 0, buf, patwidth);
  179.   }
  180. }
  181.  
  182. static void TrakSetWin(int xpos, int wid, int ypos, int hgt)
  183. {
  184.   patfirst=ypos;
  185.   patheight=hgt;
  186.   patwidth=wid;
  187. }
  188.  
  189. static int TrakGetWin(cpitextmodequerystruct &q)
  190. {
  191.   if (!plTrackActive)
  192.     return 0;
  193.  
  194.   q.hgtmin=3;
  195.   q.hgtmax=100;
  196.   q.xmode=1;
  197.   q.size=2;
  198.   q.top=0;
  199.   q.killprio=64;
  200.   q.viewprio=160;
  201.   return 1;
  202. }
  203.  
  204. static int TrakIProcessKey(unsigned short key)
  205. {
  206.   switch (key)
  207.   {
  208.   case 't': case 'T':
  209.     cpiTextSetMode("trak");
  210.     break;
  211.   case 'x': case 'X':
  212.     plTrackActive=1;
  213.     return 0;
  214.   case 0x2d00: //alt-x
  215.     plTrackActive=0;
  216.     return 0;
  217.   default:
  218.     return 0;
  219.   }
  220.   return 1;
  221. }
  222.  
  223. static int TrakAProcessKey(unsigned short key)
  224. {
  225.   switch (key)
  226.   {
  227.   case 't': case 'T':
  228.     plTrackActive=!plTrackActive;
  229.     cpiTextRecalc();
  230.     break;
  231.   }
  232.   return 1;
  233. }
  234.  
  235. static int trkEvent(int ev)
  236. {
  237.   return 1;
  238. }
  239.  
  240. static cpitextmoderegstruct xmpTrakMode = {"trak", TrakGetWin, TrakSetWin, xmpDrawPattern, TrakIProcessKey, TrakAProcessKey, trkEvent};
  241.  
  242.  
  243. //************************************************************************
  244.  
  245. static void logvolbar(int &l, int &r)
  246. {
  247.   if (l>32)
  248.     l=32+((l-32)>>1);
  249.   if (l>48)
  250.     l=48+((l-48)>>1);
  251.   if (l>56)
  252.     l=56+((l-56)>>1);
  253.   if (l>64)
  254.     l=64;
  255.   if (r>32)
  256.     r=32+((r-32)>>1);
  257.   if (r>48)
  258.     r=48+((r-48)>>1);
  259.   if (r>56)
  260.     r=56+((r-56)>>1);
  261.   if (r>64)
  262.     r=64;
  263. }
  264.  
  265. static void drawvolbar(short *buf, int i, unsigned char st)
  266. {
  267.   int l,r;
  268.   xmpGetRealVolume(i, l, r);
  269.   logvolbar(l, r);
  270.  
  271.   l=(l+4)>>3;
  272.   r=(r+4)>>3;
  273.   if (plPause)
  274.     l=r=0;
  275.   if (st)
  276.   {
  277.     writestring(buf, 8-l, 0x08, "■■■■■■■■", l);
  278.     writestring(buf, 9, 0x08, "■■■■■■■■", r);
  279.   }
  280.   else
  281.   {
  282.     writestringattr(buf, 8-l, "■\x0F■\x0B■\x0B■\x09■\x09■\x01■\x01■\x01"+16-l-l, l);
  283.     writestringattr(buf, 9, "■\x01■\x01■\x01■\x09■\x09■\x0B■\x0B■\x0F", r);
  284.   }
  285. }
  286.  
  287. static void drawlongvolbar(short *buf, int i, unsigned char st)
  288. {
  289.   int l,r;
  290.   xmpGetRealVolume(i, l, r);
  291.   logvolbar(l, r);
  292.   l=(l+2)>>2;
  293.   r=(r+2)>>2;
  294.   if (plPause)
  295.     l=r=0;
  296.   if (st)
  297.   {
  298.     writestring(buf, 16-l, 0x08, "■■■■■■■■■■■■■■■■", l);
  299.     writestring(buf, 17, 0x08, "■■■■■■■■■■■■■■■■", r);
  300.   }
  301.   else
  302.   {
  303.     writestringattr(buf, 16-l, "■\x0F■\x0F■\x0B■\x0B■\x0B■\x0B■\x09■\x09■\x09■\x09■\x01■\x01■\x01■\x01■\x01■\x01"+32-l-l, l);
  304.     writestringattr(buf, 17, "■\x01■\x01■\x01■\x01■\x01■\x01■\x09■\x09■\x09■\x09■\x0B■\x0B■\x0B■\x0B■\x0F■\x0F", r);
  305.   }
  306. }
  307.  
  308.  
  309.  
  310.  
  311.  
  312. static void drawchannel(short *buf, int len, int i)
  313. {
  314.   unsigned char st=plMuteCh[i];
  315.  
  316.   unsigned char tcol=st?0x08:0x0F;
  317.   unsigned char tcold=st?0x08:0x07;
  318.   unsigned char tcolr=st?0x08:0x0B;
  319.  
  320.   switch (len)
  321.   {
  322.   case 36:
  323.     writestring(buf, 0, tcold, " -- --- -- ------ ········ ········ ", 36);
  324.     break;
  325.   case 62:
  326.     writestring(buf, 0, tcold, "                        ---· --· -· ------  ········ ········ ", 62);
  327.     break;
  328.   case 128:
  329.     writestring(buf,  0, tcold, "                             │                   │    │   │  │               │  ················ ················", 128);
  330.     break;
  331.   case 76:
  332.     writestring(buf,  0, tcold, "                             │    │   │  │               │ ········ ········", 76);
  333.     break;
  334.   case 44:
  335.     writestring(buf, 0, tcold, " --  ---· --· -· ------   ········ ········ ", 44);
  336.     break;
  337.   }
  338.  
  339.   if (!xmpChanActive(i))
  340.     return;
  341.  
  342.   int ins=xmpGetChanIns(i);
  343.   int smp=xmpGetChanSamp(i);
  344.   switch (len)
  345.   {
  346.   case 36:
  347.     writenum(buf,  1, tcol, ins, 16, 2, 0);
  348. /*
  349.     writestring(buf,  4, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
  350.     writenum(buf, 8, tcol, ci.vol, 16, 2, 0);
  351.     char *fxstr=getfxstr6(ci.fx);
  352.     if (fxstr)
  353.       writestring(buf, 11, tcol, fxstr, 6);
  354. */
  355.     drawvolbar(buf+18, i, st);
  356.     break;
  357.   case 62:
  358.     if (ins)
  359.       if (*insts[ins-1].name)
  360.         writestring(buf,  1, tcol, insts[ins-1].name, 21);
  361.       else
  362.       {
  363.         writestring(buf,  1, 0x08, "(  )", 4);
  364.         writenum(buf,  2, 0x08, ins, 16, 2, 0);
  365.       }
  366. /*
  367.     writestring(buf, 24, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
  368.     writestring(buf, 27, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
  369.     writenum(buf, 29, tcol, ci.vol, 16, 2, 0);
  370.     writestring(buf, 31, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
  371.     writestring(buf, 33, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
  372.     writestring(buf, 34, tcol, " \x1A\x1B"+ci.panslide, 1);
  373.     char *fxstr=getfxstr6(ci.fx);
  374.     if (fxstr)
  375.       writestring(buf, 36, tcol, fxstr, 6);
  376. */
  377.     drawvolbar(buf+44, i, st);
  378.     break;
  379.   case 76:
  380.     if (ins)
  381.       if (*insts[ins-1].name)
  382.         writestring(buf,  1, tcol, insts[ins-1].name, 28);
  383.       else
  384.       {
  385.         writestring(buf,  1, 0x08, "(  )", 4);
  386.         writenum(buf,  2, 0x08, ins, 16, 2, 0);
  387.       }
  388. /*
  389.     writestring(buf, 30, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
  390.     writestring(buf, 33, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
  391.     writenum(buf, 35, tcol, ci.vol, 16, 2, 0);
  392.     writestring(buf, 37, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
  393.     writestring(buf, 39, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
  394.     writestring(buf, 40, tcol, " \x1A\x1B"+ci.panslide, 1);
  395.  
  396.     char *fxstr=getfxstr15(ci.fx);
  397.     if (fxstr)
  398.       writestring(buf, 42, tcol, fxstr, 15);
  399.  
  400. */
  401.     drawvolbar(buf+59, i, st);
  402.     break;
  403.   case 128:
  404.     if (ins)
  405.       if (*insts[ins-1].name)
  406.         writestring(buf,  1, tcol, insts[ins-1].name, 28);
  407.       else
  408.       {
  409.         writestring(buf,  1, 0x08, "(  )", 4);
  410.         writenum(buf,  2, 0x08, ins, 16, 2, 0);
  411.       }
  412.     if (smp!=0xFFFF)
  413.       if (*samps[smp].name)
  414.         writestring(buf, 31, tcol, samps[smp].name, 17);
  415.       else
  416.       {
  417.         writestring(buf, 31, 0x08, "(    )", 6);
  418.         writenum(buf, 32, 0x08, smp, 16, 4, 0);
  419.       }
  420. /*
  421.     writestring(buf, 50, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
  422.     writestring(buf, 53, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
  423.     writenum(buf, 55, tcol, ci.vol, 16, 2, 0);
  424.     writestring(buf, 57, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
  425.     writestring(buf, 59, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
  426.     writestring(buf, 60, tcol, " \x1A\x1B"+ci.panslide, 1);
  427.  
  428.     char *fxstr=getfxstr15(ci.fx);
  429.     if (fxstr)
  430.       writestring(buf, 62, tcol, fxstr, 15);
  431. */
  432.     drawlongvolbar(buf+80, i, st);
  433.     break;
  434.   case 44:
  435.     writenum(buf,  1, tcol, xmpGetChanIns(i), 16, 2, 0);
  436. /*
  437.     writestring(buf,  5, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
  438.     writestring(buf, 8, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
  439.     writenum(buf, 10, tcol, ci.vol, 16, 2, 0);
  440.     writestring(buf, 12, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
  441.     writestring(buf, 14, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
  442.     writestring(buf, 15, tcol, " \x1A\x1B"+ci.panslide, 1);
  443.  
  444.     char *fxstr=getfxstr6(ci.fx);
  445.     if (fxstr)
  446.       writestring(buf, 17, tcol, fxstr, 6);
  447. */
  448.     drawvolbar(buf+26, i, st);
  449.     break;
  450.   }
  451. }
  452.  
  453. //************************************************************************
  454.  
  455. static int xmpGetDots(notedotsdata *d, int max)
  456. {
  457.   int pos=0;
  458.   int i,j;
  459.   for (i=0; i<plNLChan; i++)
  460.   {
  461.     if (pos>=max)
  462.       break;
  463.     int smp,frq,voll,volr,sus;
  464.     if (!xmpGetDotsData(i, smp, frq, voll, volr, sus))
  465.       continue;
  466.     d[pos].voll=voll;
  467.     d[pos].volr=volr;
  468.     d[pos].chan=i;
  469.     d[pos].note=frq;
  470.     d[pos].col=(sus?32:16)+(smp&15);//sustain
  471.     pos++;
  472.   }
  473.   return pos;
  474. }
  475.  
  476.  
  477.  
  478.  
  479. static int xmpOpenFile(const char *path, moduleinfostruct &info, binfile *file)
  480. {
  481.   if (!mcpOpenPlayer)
  482.     return errGen;
  483.  
  484.   if (!file)
  485.     return errFileOpen;
  486.  
  487.   int (*loader)(xmodule &, binfile &)=0;
  488.   switch (info.modtype)
  489.   {
  490.   case mtXM: loader=xmpLoadModule; break;
  491.   case mtMOD: loader=xmpLoadMOD; break;
  492.   }
  493.   if (!loader)
  494.     return errFormStruc;
  495.  
  496.   int retval=loader(mod, *file);
  497.  
  498.   if (retval)
  499.     xmpFreeModule(mod);
  500.  
  501.   file->close();
  502.  
  503.   if (retval)
  504.     return -1;
  505.  
  506.   insts=mod.instruments;
  507.   samps=mod.samples;
  508.   plNLChan=mod.nchan;
  509.  
  510.   plIsEnd=xmpLooped;
  511.   plIdle=xmpIdle;
  512.   plProcessKey=xmpProcessKey;
  513.   plDrawGStrings=xmpDrawGStrings;
  514.   plSetMute=xmpMute;
  515.   plGetRealMasterVolume=mcpGetRealMasterVolume;
  516.   plGetMasterSample=mcpGetMasterSample;
  517.   plGetLChanSample=xmpGetLChanSample;
  518.   plGetPChanSample=mcpGetChanSample;
  519.  
  520.   plUseDots(xmpGetDots);
  521.   plUseChannels(drawchannel);
  522.   gmdInstSetup(mod.instruments, mod.ninst, mod.samples, mod.nsamp, mod.sampleinfos, mod.nsampi, 0, xmpMarkInsSamp);
  523.   cpiTextRegisterMode(&xmpTrakMode);
  524.  
  525.   mcpNormalize();
  526.   if (!xmpPlayModule(mod))
  527.     retval=errPlay;
  528.   plNPChan=mcpNChan;
  529.  
  530.   if (retval)
  531.   {
  532.     xmpFreeModule(mod);
  533.     return retval;
  534.   }
  535.  
  536.   plPause=0;
  537.   mcpSet(-1, mcpMasterPause, 0);
  538.  
  539.   return errOk;
  540. }
  541.  
  542. extern "C"
  543. {
  544.   cpifaceplayerstruct xmpPlayer = {xmpOpenFile, xmpCloseFile};
  545. };
  546.